package com.misoneism.fire.service
{
	import com.adobe.utils.DateUtil;
	import com.google.maps.LatLng;
	import com.misoneism.fire.event.IncidentParserEvent;
	import com.misoneism.fire.model.IncidentSizeEnum;
	import com.misoneism.fire.model.IncidentStatusEnum;
	import com.misoneism.fire.model.IncidentTypeEnum;
	import com.misoneism.fire.model.MFBIncident;
	
	import flash.events.EventDispatcher;
	
	import org.as3commons.collections.ArrayList;
	import org.as3commons.collections.framework.IList;
	
	
	/**
	 * Parser used for processing an MFB incident feed.
	 */
	public class MFBIncidentParser extends EventDispatcher implements IIncidentParser
	{
		private static const STATUS_UNDER_CONTROL: String = "UNDER CONTROL";
		private static const STATUS_INVESTIGATING: String = "INVESTIGATING";
		private static const STATUS_NOT_YET_UNDER_CONTROL: String = "NOT YET UNDER CONTROL";
		private static const STATUS_INITIATED: String = "INITIATED";
		
		private static const TYPE_STRUCTURE_FIRE: String = "STRUCTURE FIRE";
		private static const TYPE_MEDICAL_EMERGENCY: String = "MEDICAL EMERGENCY";
		private static const TYPE_INCIDENT: String = "INCIDENT";
		
		public function MFBIncidentParser()
		{
		}
		
		
		/**
		 * @inheritDoc
		 */
		public function parseXML( xml: XML ): void
		{
			// Do some basic format checking
			if ( ( xml.name(  ) != "markers" ) || ( !xml.hasOwnProperty( "@updated" ) ) )
			{
				dispatchEvent( new IncidentParserEvent( IncidentParserEvent.FAILED ) );
			}
			
			// Determine the date of these items
			// NOTE: The time zone hack is applied as the AS3 Date object doesn't understand EST
			var date: Date = new Date( Date.parse( String( xml.@updated ).replace( "EST", "GMT+10" ) ) );
			
			var incidents: IList = new ArrayList(  );
			
			// Iterate over each marker
			for each ( var markerXml: XML in xml.marker )
			{
				if ( !markerXml.hasOwnProperty( "@id" ) || !markerXml.hasOwnProperty( "@lat" ) || !markerXml.hasOwnProperty( "@lng" ) ||
						!markerXml.hasOwnProperty( "@appliences" ) || !markerXml.hasOwnProperty( "@status_desc" ) ||
						!markerXml.hasOwnProperty( "@type_desc" ) )
				{
					dispatchEvent( new IncidentParserEvent( IncidentParserEvent.FAILED ) );
				}
				
				var id: uint = uint( markerXml.@id );
				var location: LatLng = new LatLng( Number( markerXml.@lat ), Number( markerXml.@lng ) );
				var appliances: uint = uint( String( markerXml.@appliences ).split( "," ).length );
				var status: IncidentStatusEnum = parseStatus( markerXml.@status_desc );
				var size: IncidentSizeEnum = IncidentSizeEnum.SPOT;
				var type: IncidentTypeEnum = parseType( markerXml.@type_desc );
				
				incidents.add( new MFBIncident( id, location, appliances, date, status, size, type ) );
			}
			
			dispatchEvent( new IncidentParserEvent( IncidentParserEvent.COMPLETED, false, false,
				incidents ) );
		}
		
		
		/**
		 * Parses the specified status description into an appropriate enum.
		 */
		private function parseStatus( status: String ): IncidentStatusEnum
		{
			if ( status == STATUS_UNDER_CONTROL )
			{
				return IncidentStatusEnum.UNDER_CONTROL;
			}
			else if ( status == STATUS_INITIATED )
			{
				return IncidentStatusEnum.INITIATED;
			}
			else if ( status == STATUS_INVESTIGATING )
			{
				return IncidentStatusEnum.INVESTIGATING;
			}
			else if ( status == STATUS_NOT_YET_UNDER_CONTROL )
			{
				return IncidentStatusEnum.NOT_YET_UNDER_CONTROL;
			}
			else
			{
				return IncidentStatusEnum.UNKNOWN;
			}
		}
		
		
		/**
		 * Parses the specified type description into an appropriate enum.
		 */
		private function parseType( type: String ): IncidentTypeEnum
		{
			if ( type == TYPE_STRUCTURE_FIRE )
			{
				return IncidentTypeEnum.STRUCTURE;
			}
			else if ( type == TYPE_MEDICAL_EMERGENCY )
			{
				return IncidentTypeEnum.MEDICAL_EMERGENCY;
			}
			else if ( type == TYPE_INCIDENT )
			{
				return IncidentTypeEnum.INCIDENT;
			}
			else
			{
				return IncidentTypeEnum.UNKNOWN;
			}
		}
	}
}